﻿using autoMessage;
using autoMessage.Config;
using autoMessage.DbContexts;
using autoMessage.Entities;
using autoMessage.Entities.Dtos;
using Microsoft.EntityFrameworkCore;
using NetAutoGUI;
using Newtonsoft.Json;
using System.Drawing;
using System.Text;
using static Org.BouncyCastle.Math.EC.ECCurve;


int lastestId = 32152;
List<string> userList = new List<string>
{
    "马桂振",
    "展旭辉",
    "孟祥健",
    "朱长亮",
    "万鸿炜",
    "肖克凡",
    "曲传璐",
    "王冬冬",
    "张鑫",
    "李歌",
    "曲俊豪",
    "吴钊",
    "安瑞",
    "于子皓"
};
List<string> adminAddress = new List<string>
{
    "952084386@qq.com"
};
bool updateFlag = false;
bool sendSuccess = false;
try
{
    //获取配置文件配置
    string jsonFilePath = "ApplicationConfig.json";
    using StreamReader sr = new StreamReader(jsonFilePath);
    string json = sr.ReadToEnd();
    var config = JsonConvert.DeserializeObject<ApplicationConfig>(json);
    if (config is null || config.UserList is null)
    {
        Console.WriteLine("配置文件有误,请勿修改Json文件中的key值");
        Console.ReadKey();
        return;
    }
    userList = config.UserList;
    lastestId = config.LastestId;
    adminAddress = config.adminAddress;
}
catch (JsonSerializationException)
{
    Console.WriteLine("配置文件有误,请按照Json格式进行修改");
    Console.ReadKey();
}
Console.WriteLine("首次判断今日是否休息");
string date = DateTime.Now.ToString("yyyy-MM-dd");
bool restFlag = await isRest(date);
Console.WriteLine(@$"今天是休息日吗：{(restFlag?"是":"否")}");
try
{
    await Task.Run(async () =>
    {
        while (true)
        {
            if (!DateTime.Now.ToString("yyyy-MM-dd").Equals(date))
            {
                //日期更新，重新判断
                date = DateTime.Now.ToString("yyyy-MM-dd");
                restFlag = await isRest(date);
            }
            if (restFlag)
            {
                Console.WriteLine($"非工作日，休眠二十四小时，开始时间:{DateTime.Now}");
                Thread.Sleep(1000 * 60 * 60 * 24);
            }
            else 
            {
                if (DateTime.Now.Hour > 7 && DateTime.Now.Hour < 18)
                {
                    Console.WriteLine($"查询开始,开始时间:{DateTime.Now}");
                    await sendMessage();
                    Console.WriteLine($"查询结束,结束时间:{DateTime.Now}");
                    Console.WriteLine("===============================");
                    Thread.Sleep(1000 * 60 * 1);
                }
                else
                {
                    Console.WriteLine($"非工作时间，休眠一小时，开始时间:{DateTime.Now}"); ;
                    Thread.Sleep(1000 * 60 * 60);
                }
            }
        }
    });
}
catch (Exception e) {

    if (!sendSuccess)
    {
        Console.WriteLine("非预期故障，向管理员发送邮件");
        var errorMessage = new StringBuilder();
        errorMessage.AppendLine("<h3>尊敬的管理员:</h3>");
        errorMessage.AppendLine($"<h4 style=\"text-indent: 2em;\">autoMessage程序出现故障,应为匹配搜索图像失败导致,请登录192.168.32.29进行处理。故障时间:{DateTime.Now}。</h4>");
        errorMessage.AppendLine($"<h4>错误信息：{e.Message}</h4>");
        errorMessage.AppendLine($"<h4>详细信息如下：<h4>");
        errorMessage.AppendLine($"<h4>{e.StackTrace}</h4>");
        errorMessage.AppendLine($"<h4 style=\"text-align:right;\">{DateTime.Now.ToString("yyyy年MM月dd日")}</h4>");
        sendSuccess = EmailHelper.MailSystem163.SendMail(
        "17663981905@163.com",
        "Messager",
        adminAddress,
        "AutoMessag程序遇到错误",
        errorMessage.ToString(),
        null,
        true
        );
    }
    Console.WriteLine(e.Message);
    Console.WriteLine(e.StackTrace);
    Console.ReadKey();
}

async Task<bool> isRest(string date)
{
    HttpClient client = new();
    //免费API，若IP被限制或服务器宕机则直接视为工作日
    try
    {
        var responseString = await client.GetStringAsync($"https://timor.tech/api/holiday/info/{date}");
        var result = JsonConvert.DeserializeObject<Result>(responseString);
        // 0服务正常。-1服务出错
        if (result.code == -1)
            return false;
        //Type表示节假日类型，0123分别表示 工作日、周末、节日、调休。
        if (result.Type.Type == 1 || result.Type.Type == 2)
            return true;
        return false;
    }
    catch (HttpRequestException)
    {
        return false;
    }
}

async Task sendMessage()
{
    //初始化数据库连接
    using ItsContext ctx = new();
    //获取状态为未开始的事件
    var terminalEvents = await ctx.ClientEvents
        .AsNoTracking()//取消实体追踪
        .Where(x => x.ClientEventId > lastestId && x.ClientEventStatus == 0)
        .Select(y => new ClientEventOutput
        {
            ClientEventId = y.ClientEventId,
            ClientEventNum = y.ClientEventNum,
            ClientEventDescription = y.ClientEventDescription,
            ClientEventReporter = y.ClientEventReporter,
            ClientEventReporterNum = y.ClientEventReporterNum,
            ClientEventReporterTel = y.ClientEventReporterTel,
            ClientEventReportTime = y.ClientEventReportTime,
            ClientEventStatus = y.ClientEventStatus,
            //因数据库配置及实体类为反向工程生成，故无法使用include直接获取
            ClientEventHandler = ctx.SysUsers.Where(z => z.UserId == y.ClientEventHandlerId).Select(x => x.UserName).First()
        }).ToListAsync();
    foreach (var terminalEvent in terminalEvents)
    {
        //若处理人为空或处理人不在列表内则跳过
        if (terminalEvent.ClientEventHandler == null || ! userList!.Exists(x=>x==terminalEvent.ClientEventHandler))
            continue;
        await Task.Run(() => SendWxMegForUser(terminalEvent));
        lastestId = updateFlag ? terminalEvent.ClientEventId : lastestId;
        Console.WriteLine($"当前最新ID：{lastestId}");
        //若本次更新失败则跳出本次循环
        if (!updateFlag)
        {
            break;
        }
    }
}
void SendWxMegForUser(ClientEventOutput clientEventOutput)
{
    #region 激活微信窗口
    Window? windows = GUI.Application.FindWindowByTitle("微信");
    //若不存在窗口
    if (windows is null)
    {
        #region 使用小图标开启

        ////匹配微信小图标
        //var rectWxIcon = GUI.Screenshot.LocateOnScreen("img/wechat.png");
        ////若未能匹配到
        //if (rectWxIcon == null)
        //{
        //    Console.WriteLine($"未找到{title}托盘图标,请确认是否已开启应用并显示托盘图标");
        //    Console.ReadKey();
        //    //结束进程
        //    GUI.Keyboard.HotKey(VirtualKeyCode.CONTROL, VirtualKeyCode.VK_C);
        //}
        ////唤起窗口
        //GUI.Mouse.Click(rectWxIcon.X, rectWxIcon.Y);
        //windows = GUI.Application.WaitForWindowByTitle(title);

        #endregion

        Console.WriteLine("因为任务栏不存在窗口所以本次发送终止");
        //结束本次查询
        updateFlag = false;
        return;
    }
    Console.WriteLine("正在激活窗口");
    windows!.Activate();
    #endregion
    Thread.Sleep(1500);
    //windows.Maximize();
    //匹配搜索图标
    try
    {
        Console.WriteLine("正在匹配搜索");
        try
        {
            Console.WriteLine("第一次匹配搜索");
            //降低置信区间提高匹配率
            windows!.WaitAndClick("img/search.png", 0.8);
        }
        catch (Exception)
        {
            Console.WriteLine("第二次匹配搜索");
            windows!.WaitAndClick("img/search2.png", 0.8);
        }
    }
    catch (Exception e)
    {
        if (!sendSuccess)
        {
            Console.WriteLine("匹配失败，向管理员发送邮件");
            var errorMessage = new StringBuilder();
            errorMessage.AppendLine("<h3>尊敬的管理员:</h3>");
            errorMessage.AppendLine($"<h4 style=\"text-indent: 2em;\">autoMessage程序出现故障,应为匹配搜索图像失败导致,请登录192.168.32.29进行处理。故障时间:{DateTime.Now}。</h4>");
            errorMessage.AppendLine($"<h4>错误信息：{e.Message}</h4>");
            errorMessage.AppendLine($"<h4>详细信息如下：<h4>");
            errorMessage.AppendLine($"<h4>{e.StackTrace}</h4>");
            errorMessage.AppendLine($"<h4 style=\"text-align:right;\">{DateTime.Now.ToString("yyyy年MM月dd日")}</h4>");
            sendSuccess = EmailHelper.MailSystem163.SendMail(
            "17663981905@163.com",
            "Messager",
            adminAddress,
            "AutoMessag程序遇到错误",
            errorMessage.ToString(),
            null,
            true
            );
        }
        updateFlag = false;
        return;
    }
    sendSuccess = false;
    Console.WriteLine("匹配成功，选取联系人");
    //选取联系人
    WriteInfo(clientEventOutput.ClientEventHandler!, changeLine: false);
    Confirm();
    //写入消息
    Console.WriteLine("模拟输入开始");
    WriteInfo("您有新的事件需要处理");
    WriteInfo("======================");
    WriteInfo($"事件编号:{clientEventOutput.ClientEventNum}");
    WriteInfo($"事件描述:{clientEventOutput.ClientEventDescription}");
    WriteInfo($"事件上报人:{clientEventOutput.ClientEventReporter}");
    WriteInfo($"事件上报人工号:{clientEventOutput.ClientEventReporterNum}");
    WriteInfo($"上报人电话号码:{clientEventOutput.ClientEventReporterTel}");
    WriteInfo($"事件上报时间:{clientEventOutput.ClientEventReportTime}");
    WriteInfo($"事件处理人:{clientEventOutput.ClientEventHandler}", changeLine: false);
    Confirm();
    Console.WriteLine("模拟输入完成");
    updateFlag = true;
}


/// <summary>
/// 模拟输入信息
/// </summary>
/// <param name="message">写入的信息</param>
/// <param name="interval">每个字符的输入间隔时间</param>
/// <param name="sleepTime">输入后线程休眠时间</param>
/// <param name="changeLine">是否换行</param>
void WriteInfo(string message, double interval = 0, int sleepTime = 1000, bool changeLine = true)
{
    Thread.Sleep(sleepTime);
    GUI.Keyboard.Write(message, interval);
    if (changeLine)
        ChangeLine();
}

void ChangeLine()
{
    Thread.Sleep(1000);
    GUI.Keyboard.HotKey(VirtualKeyCode.CONTROL, VirtualKeyCode.RETURN);
}

void Confirm() 
{
    Thread.Sleep(1000);
    GUI.Keyboard.Press(VirtualKeyCode.RETURN);
}